/**
  ******************************************************************************
  * @file           : storage.h
  * @brief          : This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STORAGE_H
#define __STORAGE_H

#include <stdint.h>
#include "bsp.h"
#include "mb85rs64.h"
#include "tskcfg.h"

#define STORAGE_QUE_LENGTH         20
#define STORAGE_QUE_ITEMSIZE       sizeof(Sto_CmdStru)


#define STG_UPCB_PREFIX(x)         (storage_upcb_##x)
#define STG_INDEX_PREFIX(x)        (PARA_##x##_IDX)
#define ID2ADD_PREFIX(x)           ID2ADD(STG_INDEX_PREFIX(x))

typedef union _Sto_CellUnion
{
  uint8_t  ut8;
  uint16_t ut16;
  int16_t  st16;
  uint32_t ut32;
  int32_t  st32;
  uint64_t ut64;
  int64_t  st64;
  double   db64;
  uint8_t  ua8[8];
  uint16_t ua16[4];
  Sys_DataTimeStru dt;
}Sto_CellUnion;

typedef struct _Sto_DataStru
{
  Sto_CellUnion para;
  uint16_t      crc16;
}Sto_DataStru;

typedef struct _Sto_DescribeStrStru
{
  const char *name1;    /* 名称字符串-参数页显示的标题 */
  const char *name2;    /* 名称字符串-输入页显示的标题 */
  const char *unit;     /* 单位字符串 */
  const char *brief;    /* 描述字符串 */
}Sto_DescribeStrStru;

/* 参数维护表 */
typedef struct _Sto_MaintainStru
{
  uint8_t  idx;                                  /* 数据编号,检索条件 */
  uint8_t  page;                                 /* 用于显示的页面号(非ssid) 检索条件 */
  uint8_t  focus;                                /* 用于显示的页面中焦点号 检索条件 */
  uint16_t addr;                                 /* 在FRAM里的存储地址 */
  const Sto_DescribeStrStru *fixstr;             /* 描述字符串 */
  uint8_t (*dynstr)(const struct _Sto_MaintainStru *, uint8_t, char *, uint16_t);  /* 显示回调函数:用于绑定特定对象并将其转换为显示字符串 */
  uint8_t (*ckcb)(const Sto_CellUnion, const Sto_CellUnion, const Sto_CellUnion);  /* 参数校验回调 */
  void (*upcb)(uint16_t, Sto_CellUnion, void *); /* 目标更新回调 */
  uint8_t (*input)(const struct _Sto_MaintainStru *, uint8_t, uint8_t);    /* 界面输入回调 */
  char *inputbuf;                                /* 界面输入buf */
  volatile uint8_t *inputpos;                    /* 界面输入buf偏移 */
  Sto_CellUnion init;                            /* 初始值 */
  Sto_CellUnion max;                             /* 最大值 */
  Sto_CellUnion min;                             /* 最小值 */
}Sto_MaintainStru;

typedef struct _Sto_MaintTableStru
{
  uint8_t tablesize;                     /* "维护表"内项目数量 */
  uint8_t saveidxend;                   /* 索引号结尾 */
  const   Sto_MaintainStru *maint;  /* 参数维护表地址 */
}Sto_MaintainTableStru;

typedef enum _Sto_CmdEnum
{
  STO_CMD_INIT_ITEM,
  STO_CMD_GET_ITEM,
  STO_CMD_SET_ITEM,
  STO_CMD_INIT_ALLITEMS,
  STO_CMD_GET_ALLITEMS,
}Sto_CmdEnum;

typedef struct _Sto_CmdStru
{
  Sto_CmdEnum   cmd;
  uint8_t       idx;
  Sto_CellUnion dat;
}Sto_CmdStru;

/* 一些通用校验回调函数 */
extern uint8_t sto_ckcb_general_bool(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_datatime(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_ziptime32(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_ut8(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_ut16(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_ut16_with0(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_st16(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_ut32(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_st32(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_ut64(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_ip(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);
extern uint8_t sto_ckcb_general_mac(const Sto_CellUnion dat, const Sto_CellUnion max, const Sto_CellUnion min);

extern const Sto_MaintainStru *sto_find_mt_with_uipos(uint8_t page, uint8_t focus, const Sto_MaintainTableStru *mttb);

/**
  * @brief  初始化单个项目并存储
  * @param  None
  * @retval None
  */
extern uint8_t sto_init_item(uint8_t idx, const Sto_MaintainTableStru *tb, void *dest);

/**
  * @brief  从存储中读取一个项目(并校验)
  * @param  None
  * @retval None
  */
extern uint8_t sto_get_item(uint8_t idx, const Sto_MaintainTableStru *tb, void *dest);

/**
  * @brief  向存储中写入一个项目(并校验)
  * @param  None
  * @retval None
  */
extern uint8_t sto_set_item(uint8_t idx, const Sto_CellUnion *dat, const Sto_MaintainTableStru *tb, void *dest);

/**
  * @brief  初始化所有项目并存储
  * @param  None
  * @retval None
  */
extern uint8_t sto_init_allitems(const Sto_MaintainTableStru *tb);

/**
  * @brief  从存储中读取所有项目(并校验)
  * @param  None
  * @retval None
  */
extern uint8_t sto_get_allitems(const Sto_MaintainTableStru *tb);

extern void sto_update_item(uint8_t idx, const Sto_CellUnion *dat, TickType_t mxdelay);
extern void sto_reset_allitems(TickType_t mxdelay);

extern volatile uint16_t sto_save_feedback;

#endif /* __STORAGE_H */
